package cn.monkey.transport.netty.server.codec.protocol;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Objects;

record ServerPortBindingProtocolRouterFunction(ServerProtocolRouterFunction delegate,
                                               int... ports) implements ServerProtocolRouterFunction {

    private static final Logger log = LoggerFactory.getLogger(ServerPortBindingProtocolRouterFunction.class);

    ServerPortBindingProtocolRouterFunction {
        Objects.requireNonNull(delegate, "delegate matcher can not be null");
        if (ports == null || ports.length == 0) {
            throw new IllegalArgumentException("port can not be null or empty");
        }
    }

    @Override
    public boolean test(Channel channel, Object data) {
        if (!this.delegate.test(channel, data)) {
            return false;
        }
        Channel parent;
        if ((parent = channel.parent()) == null) {
            return false;
        }
        SocketAddress socketAddress = parent.localAddress();
        if (socketAddress instanceof InetSocketAddress inetSocketAddress) {
            for (int port : this.ports) {
                if (port == inetSocketAddress.getPort()) {
                    return true;
                }
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("no matching port: {} for data: {}", this.ports, data);
        }
        return false;
    }

    @Override
    public void accept(Channel channel) {
        this.delegate.accept(channel);
    }
}
